package com.xht.transaction.service;

import com.xht.transaction.data.UserData;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 订单服务层
 */
@Service
public class OrderService {

    @Autowired
    private UserData userData;

    @Autowired
    private StockService stockService;


    /**
     * 事务的默认传播行为: REQUIRED
     * 该方法下的其他方案都会继承该事务
     * @return
     */
    @Transactional
    public Boolean order(){
        Boolean result = userData.insert("下单");
        stockService.stock();
        return result;
    }


    /**
     * 事务传播行为: SUPPORTS
     * SUPPORTS 只能子事务被父事务调用，不能直接调用否则不生效，
     * SUPPORTS 传播事务 建议使用于查询操作
     * @return
     */
    @Transactional
    public Boolean order2(){
        Boolean result = userData.insert("下单");
        stockService.stockSupports();
        return result;
    }

    /**
     * 事务传播行为:REQUIRES_NEW
     * 当前方法中再addLog方法重新开启一个新的事物
     * @return
     */
    @Transactional
    public Boolean order3(){
        Boolean result = userData.insert("下单");
        stockService.stock2();
        stockService.addLog();
        int a = 1 / 0;
        return result;
    }

    /**
     * 事务传播行为:NEVER
     * 子事务存在会直接抛抛出异常
     * @return
     */
    @Transactional
    public Boolean order4(){
        Boolean result = userData.insert("下单");
        stockService.never();
        return result;
    }

    /**
     * 事务传播行为:MANDATORY
     * 直接调用事务时又会抛异常
     * 如果存在两个特殊的业务，有强依赖时可以使用
     * @return
     */
    @Transactional
    public Boolean order5(){
        Boolean result = userData.insert("下单");
        stockService.mandatory();
        return result;
    }

    @Transactional
    public Boolean lose(){
        Boolean result = userData.insert("lose");
        OrderService orderService = (OrderService) AopContext.currentProxy();
        orderService.lose2();
        return result;
    }

    @Transactional
    public Boolean lose2(){
        Boolean result = userData.insert("lose2");
        System.out.println(1 / 0);
        return result;
    }

}
